package org.dsapr;

import org.dsapr.util.ArrayUtil;

import static org.dsapr.util.ArrayUtil.isNotOutOfBounds;

public class Cells {
//	public static final String point = new String(Character.toChars(9632));
//	public static final String point = new String("⬛");
	public static final String point = "\u2588\u2588";
	private final boolean DEAD = false;
	private final boolean LIVE = true;
	private boolean[][] map;

	public Cells() {
		this.map = new boolean[Playground.width][Playground.height];
		ArrayUtil.fillTrueRandom(this.map, 1);
	}

	public void updateState() {
		boolean[][] newMap = new boolean[map.length][map[0].length];

		for(int i = 0; i < Playground.width; ++i) {
			for(int j = 0; j < Playground.height; j++) {
				newMap[i][j] = this.isKeepLive(i, j);
			}
		}

		this.map = newMap;
	}

	public boolean[][] getMap() {
		return this.map;
	}

	public boolean isKeepLive(int x, int y) {
		int pointCount = this.getNeighborsCount(x, y);
		if (this.map[x][y]) {
			if (pointCount < 2) {
				return DEAD;
			}
			if (pointCount == 2 || pointCount == 3) {
				return this.map[x][y];
			}
			if (pointCount > 3) {
				return DEAD;
			}
		} else {
			if (pointCount == 3) {
				return LIVE;
			}
		}
		return map[x][y];
	}

	public int getNeighborsCount(int x, int y) {
		int count = 0;
		if (isNotOutOfBounds(this.map, x - 1, y - 1) && this.map[x - 1][y - 1]) ++count;
		if (isNotOutOfBounds(this.map, x - 1, y) && this.map[x - 1][y]) ++count;
		if (isNotOutOfBounds(this.map, x - 1, y + 1) && this.map[x - 1][y + 1]) ++count;

		if (isNotOutOfBounds(this.map, x, y - 1) && this.map[x][y - 1]) ++count;
		if (isNotOutOfBounds(this.map, x, y + 1) && this.map[x][y + 1]) ++count;

		if (isNotOutOfBounds(this.map, x + 1, y - 1) && this.map[x + 1][y - 1]) ++count;
		if (isNotOutOfBounds(this.map, x + 1, y) && this.map[x + 1][y]) ++count;
		if (isNotOutOfBounds(this.map, x + 1, y + 1) && this.map[x + 1][y + 1]) ++count;
		return count;
	}
}
